# -*- encoding: utf-8 -*-
##############################################################################
#
##############################################################################

from odoo import api, fields, models, _
from odoo.addons import decimal_precision as dp
from odoo.exceptions import UserError, ValidationError
from odoo.tools import float_round


class mrp_bom(models.Model):
    _inherit = 'mrp.bom'

    # get_attrition = fields.Boolean(u'考虑耗损', default=False)


    def explode(self, product, quantity, picking_type=False):
        """
            Explodes the BoM and creates two lists with all the information you need: bom_done and line_done
            Quantity describes the number of times you need the BoM: so the quantity divided by the number created by the BoM
            and converted into its UoM
        """
        boms_done = [(self, {'qty': quantity, 'product': product, 'original_qty': quantity, 'parent_line': False})]
        lines_done = []
        templates_done = product.product_tmpl_id

        bom_lines = [(bom_line, product, quantity, False) for bom_line in self.bom_line_ids]
        while bom_lines:
            current_line, current_product, current_qty, parent_line = bom_lines[0]
            bom_lines = bom_lines[1:]

            if current_line._skip_bom_line(current_product):
                continue
            if current_line.product_id.product_tmpl_id in templates_done:
                raise UserError(_(
                    'Recursion error!  A product with a Bill of Material should not have itself in its BoM or child BoMs!'))
            # 计入耗损用量
            line_quantity = current_qty * current_line.product_qty * (
            current_line.attrition_rate + 1) + current_line.attrition_fixed
            mrp_standard_use = current_qty * current_line.product_qty
            line_note = current_line.note
            bom = self._bom_find(product=current_line.product_id, picking_type=picking_type or self.picking_type_id,
                                 company_id=self.company_id.id)
            # 如果bom是集合
            if bom.type == 'phantom':
                converted_mrp_standard_use = current_line.product_uom_id._compute_quantity(
                    mrp_standard_use / bom.product_qty, bom.product_uom_id)
                converted_line_quantity = current_line.product_uom_id._compute_quantity(line_quantity / bom.product_qty,
                                                                                        bom.product_uom_id)
                bom_lines = [(line, current_line.product_id, converted_line_quantity, current_line) for line in
                             bom.bom_line_ids] + bom_lines
                templates_done |= current_line.product_id.product_tmpl_id
                boms_done.append((bom, {'qty': converted_line_quantity,
                                        'mrp_standard_use': converted_mrp_standard_use,
                                        'product': current_product,
                                        'original_qty': quantity,
                                        'parent_line': current_line}))
            else:
                # We round up here because the user expects that if he has to consume a little more, the whole UOM unit
                # should be consumed.
                rounding = current_line.product_uom_id.rounding
                # 向上舍入
                line_quantity = float_round(line_quantity, precision_rounding=rounding, rounding_method='UP')
                mrp_standard_use = float_round(mrp_standard_use, precision_rounding=rounding, rounding_method='UP')
                lines_done.append((current_line, {'qty': line_quantity,
                                                  'mrp_standard_use': mrp_standard_use,
                                                  'product': current_product,
                                                  'original_qty': quantity,
                                                  'parent_line': parent_line,
                                                  'bom_line_note': line_note
                                                  }))

        return boms_done, lines_done


class mrp_bom_line(models.Model):
    _inherit = 'mrp.bom.line'

    feed_rate = fields.Float(u'投料浮动范围(正负%)', default=0.0)
    attrition_rate = fields.Float(u'耗损率', digits=(16, 3), default=0.0)
    attrition_fixed = fields.Float(u'固定耗损', default=0.0)
    note = fields.Char(u"备注")


class mrp_production_compute_line(models.Model):
    _name = 'mrp.production.compute.line'

    name = fields.Many2one('mrp.production', string=u'生产单')
    product_id = fields.Many2one('product.product', string=u'物料')
    product_uom_qty = fields.Float(u'完工数标准用量')
    quantity_done = fields.Float(u'已投料')
    product_uom_id = fields.Many2one('product.uom', u'单位')
    mrp_standard_use = fields.Float(u'基准用量', default=0.0)
    # standard_attrition_rate = fields.Float(u'基准耗损(%)', digits=(16, 3), compute='_get_attrition_rate')
    actual_attrition_rate = fields.Float(u'实际耗损(%)', digits=(16, 3), compute='_get_attrition_rate')
    mrp_production_product = fields.Many2one(related='name.product_id', string=u'生产产品')
    bom_line_id = fields.Many2one('mrp.bom.line', u"bom行")
    feed_rate = fields.Float(u'投料浮动范围(正负%)', digits=(16, 3), related='bom_line_id.feed_rate', store=True)

    # 计算耗损率
    @api.one
    def _get_attrition_rate(self):
        if self.mrp_standard_use <> 0 and self.product_uom_qty:
            # self.standard_attrition_rate=(self.product_uom_qty-self.mrp_standard_use)/self.mrp_standard_use*100
            self.actual_attrition_rate = (self.quantity_done - self.product_uom_qty) / self.product_uom_qty * 100


class MrpProduction(models.Model):
    """ Manufacturing Orders """
    _inherit = 'mrp.production'

    compute_lines = fields.One2many('mrp.production.compute.line', 'name', u'耗损详情')

    # 填入基准用量
    def _generate_raw_move(self, bom_line, line_data):
        res = super(MrpProduction, self)._generate_raw_move(bom_line, line_data)
        if line_data.get('mrp_standard_use', False):
            res.mrp_standard_use = line_data['mrp_standard_use']
        if line_data.get('bom_line_note', False):
            res.bom_line_note = line_data["bom_line_note"]
        return res
